package com.atguigu.srb.core.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.atguigu.srb.common.exception.BusinessException;
import com.atguigu.srb.core.enums.BorrowerStatusEnum;
import com.atguigu.srb.core.enums.IntegralEnum;
import com.atguigu.srb.core.mapper.BorrowerAttachMapper;
import com.atguigu.srb.core.mapper.BorrowerMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.mapper.UserIntegralMapper;
import com.atguigu.srb.core.pojo.entity.Borrower;
import com.atguigu.srb.core.pojo.entity.BorrowerAttach;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.entity.UserIntegral;
import com.atguigu.srb.core.pojo.vo.BorrowerApprovalVO;
import com.atguigu.srb.core.pojo.vo.BorrowerDetailVO;
import com.atguigu.srb.core.pojo.vo.BorrowerVO;
import com.atguigu.srb.core.service.BorrowerAttachService;
import com.atguigu.srb.core.service.BorrowerService;
import com.atguigu.srb.core.service.DictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 借款人 服务实现类
 * </p>
 *
 * @author javaCode
 * @since 2025-07-19
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class BorrowerServiceImpl extends ServiceImpl<BorrowerMapper, Borrower> implements BorrowerService {

    // 借款人上传资源表 Mapper 接口
    private final BorrowerAttachMapper borrowerAttachMapper;

    // 用户基本信息 Mapper 接口
    private final UserInfoMapper userInfoMapper;

    // 数据字典 服务类
    private final DictService dictService;

    // 借款人上传资源表 服务类
    private final BorrowerAttachService borrowerAttachService;

    // 用户积分记录表 Mapper 接口
    private final UserIntegralMapper userIntegralMapper;

    /**
     * 保存借款人信息并更新认证状态
     *
     * @param borrowerVO 借款人表单数据
     * @param userId     用户ID
     * @throws BusinessException 业务异常，包含错误码和错误信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBorrowerVOByUserId(BorrowerVO borrowerVO, Long userId) {
        log.info("开始处理借款人信息保存流程，用户ID：{}", userId);

        // 校验用户是否存在
        UserInfo userInfo = Optional.ofNullable(userInfoMapper.selectById(userId)).orElseThrow(() -> {
            log.error("用户不存在，用户ID：{}", userId);
            return new BusinessException("用户不存在");
        });

        // 校验用户是否已认证
        if (userInfo.getBorrowAuthStatus() != BorrowerStatusEnum.NO_AUTH.getStatus()) {
            log.error("用户已处于认证流程中或已完成认证，用户ID：{}，当前状态：{}", userId, BorrowerStatusEnum.getMsgByStatus(userInfo.getBorrowAuthStatus()));
            throw new BusinessException("用户已处于认证流程中或已完成认证");
        }

        // 构建借款人实体
        log.debug("开始构建借款人实体，用户ID：{}", userId);
        Borrower borrower = new Borrower();
        BeanUtils.copyProperties(borrowerVO, borrower);
        borrower.setIsMarry(borrowerVO.getMarry());
        borrower.setUserId(userId);
        borrower.setName(userInfo.getName());
        borrower.setIdCard(userInfo.getIdCard());
        borrower.setMobile(userInfo.getMobile());
        borrower.setStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());

        // 保存借款人信息
        log.info("开始保存借款人信息，用户ID：{}", userId);
        int insertCount = baseMapper.insert(borrower);
        if (insertCount != 1) {
            log.error("借款人信息保存失败，用户ID：{}，插入影响行数：{}", userId, insertCount);
            throw new BusinessException("借款人信息保存失败");
        }
        log.info("借款人信息保存成功，用户ID：{}，借款人ID：{}", userId, borrower.getId());

        // 批量保存附件
        List<BorrowerAttach> attachList = borrowerVO.getBorrowerAttachList();
        if (CollectionUtils.isNotEmpty(attachList)) {
            final int batchSize = 50;
            final Long borrowerId = borrower.getId();

            log.info("开始保存借款人附件，借款人ID：{}，附件数量：{}", borrowerId, attachList.size());

            // 设置附件关联ID
            attachList.forEach(attach -> attach.setBorrowerId(borrowerId));

            // 分批处理附件保存，每批50条记录
            for (int i = 0; i < attachList.size(); i += batchSize) {
                List<BorrowerAttach> batchList = attachList.subList(i, Math.min(i + batchSize, attachList.size()));
                log.debug("保存附件批次，借款人ID：{}，批次：{}/{}，当前批次数量：{}", borrowerId, i / batchSize + 1, (int) Math.ceil((double) attachList.size() / batchSize), batchList.size());
                batchList.forEach(borrowerAttachMapper::insert);
            }

            log.info("借款人附件保存完成，借款人ID：{}", borrowerId);
        } else {
            log.warn("借款人附件列表为空，借款人ID：{}", borrower.getId());
        }

        // 更新会员认证状态
        log.info("开始更新用户认证状态，用户ID：{}，新状态：{}", userId, BorrowerStatusEnum.AUTH_RUN.getMsg());
        UserInfo updateInfo = new UserInfo();
        updateInfo.setId(userId);
        updateInfo.setBorrowAuthStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());

        int updateCount = userInfoMapper.updateById(updateInfo);
        if (updateCount != 1) {
            log.error("用户认证状态更新失败，用户ID：{}，更新影响行数：{}", userId, updateCount);
            throw new BusinessException("用户认证状态更新失败");
        }

        log.info("借款人信息保存流程完成，用户ID：{}，借款人ID：{}", userId, borrower.getId());
    }

    /**
     * 获取借款人认证状态
     */
    @Override
    public Integer getStatusByUserId(Long userId) {
        LambdaQueryWrapper<Borrower> wrapper = new LambdaQueryWrapper<Borrower>().select(Borrower::getStatus).eq(Borrower::getUserId, userId).orderByDesc(Borrower::getCreateTime);

        List<Object> objects = baseMapper.selectObjs(wrapper);

        if (objects.size() == 0) {
            // 借款人尚未提交信息
            return BorrowerStatusEnum.NO_AUTH.getStatus();
        }
        Integer status = (Integer) objects.get(0);
        return status;
    }

    /**
     * 获取借款人分页列表
     */
    @Override
    public IPage<Borrower> listPage(Page<Borrower> pageParam, String keyword) {
        LambdaQueryWrapper<Borrower> wrapper = new LambdaQueryWrapper<>();

        // 添加搜索条件（如果关键词不为空）
        if (StringUtils.isNotEmpty(keyword)) {
            wrapper.and(w -> w
                    .like(Borrower::getName, keyword)
                    .or().like(Borrower::getIdCard, keyword)
                    .or().like(Borrower::getMobile, keyword)
            );
        }

        // 统一添加排序条件
        wrapper.orderByDesc(Borrower::getId);

        return baseMapper.selectPage(pageParam, wrapper);
    }

    /**
     * 获取借款人信息
     */
    @Override
    public BorrowerDetailVO getBorrowerDetailVOById(Long id) {
        // 防御性编程：处理id为空的情况
        if (id == null) {
            return null;
        }

        // 获取借款人信息
        Borrower borrower = this.baseMapper.selectById(id);

        // 借款人不存在，返回空对象
        if (borrower == null) {
            return new BorrowerDetailVO();
        }

        // 填充基本借款人信息
        BorrowerDetailVO vo = new BorrowerDetailVO();
        BeanUtils.copyProperties(borrower, vo);

        // 设置简单属性
        vo.setMarry(borrower.getIsMarry() ? "是" : "否");
        vo.setSex(borrower.getSex() == 1 ? "男" : "女");
        vo.setStatus(BorrowerStatusEnum.getMsgByStatus(borrower.getStatus()));

        // 直接设置字典属性（保持在一个方法内）
        vo.setEducation(getDictValue("education", borrower.getEducation()));
        vo.setIndustry(getDictValue("moneyUse", borrower.getIndustry()));
        vo.setIncome(getDictValue("income", borrower.getIncome()));
        vo.setReturnSource(getDictValue("returnSource", borrower.getReturnSource()));
        vo.setContactsRelation(getDictValue("relation", borrower.getContactsRelation()));

        // 获取附件VO列表
        vo.setBorrowerAttachVOList(borrowerAttachService.selectBorrowerAttachVOList(id));

        return vo;
    }

    /**
     * 借款额度审批
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void approval(BorrowerApprovalVO approvalVO) {
        // 获取借款人信息并更新状态
        Borrower borrower = baseMapper.selectById(approvalVO.getBorrowerId());
        Assert.notNull(borrower, "借款人不存在");
        borrower.setStatus(approvalVO.getStatus());
        baseMapper.updateById(borrower);

        // 获取用户信息
        UserInfo userInfo = userInfoMapper.selectById(borrower.getUserId());
        Assert.notNull(userInfo, "用户信息不存在");

        // 计算总积分
        int totalIntegral = approvalVO.getInfoIntegral();

        // 添加基本信息积分记录
        UserIntegral userIntegral = new UserIntegral();
        userIntegral.setUserId(userInfo.getId());
        userIntegral.setIntegral(totalIntegral);
        userIntegral.setContent("借款人基本信息");
        userIntegralMapper.insert(userIntegral);

        // 添加身份证积分（如果已认证）
        if (approvalVO.getIsIdCardOk()) {
            int idCardIntegral = IntegralEnum.BORROWER_IDCARD.getIntegral();
            totalIntegral += idCardIntegral;

            userIntegral = new UserIntegral();
            userIntegral.setUserId(userInfo.getId());
            userIntegral.setIntegral(idCardIntegral);
            userIntegral.setContent(IntegralEnum.BORROWER_IDCARD.getMsg());
            userIntegralMapper.insert(userIntegral);
        }

        // 添加房产积分（如果已认证）
        if (approvalVO.getIsHouseOk()) {
            int houseIntegral = IntegralEnum.BORROWER_HOUSE.getIntegral();
            totalIntegral += houseIntegral;

            userIntegral = new UserIntegral();
            userIntegral.setUserId(userInfo.getId());
            userIntegral.setIntegral(houseIntegral);
            userIntegral.setContent(IntegralEnum.BORROWER_HOUSE.getMsg());
            userIntegralMapper.insert(userIntegral);
        }

        // 添加车产积分（如果已认证）
        if (approvalVO.getIsCarOk()) {
            int carIntegral = IntegralEnum.BORROWER_CAR.getIntegral();
            totalIntegral += carIntegral;

            userIntegral = new UserIntegral();
            userIntegral.setUserId(userInfo.getId());
            userIntegral.setIntegral(carIntegral);
            userIntegral.setContent(IntegralEnum.BORROWER_CAR.getMsg());
            userIntegralMapper.insert(userIntegral);
        }

        // 更新用户积分和认证状态
        userInfo.setIntegral(totalIntegral);
        userInfo.setBorrowAuthStatus(approvalVO.getStatus());
        userInfoMapper.updateById(userInfo);
    }

    /**
     * 内部方法：根据字典编码和值获取字典名称（保持在同一个类中）
     */
    private String getDictValue(String dictCode, Integer value) {
        return (value != null) ? dictService.getNameByParentDictCodeAndValue(dictCode, value) : "";
    }
}
